﻿using DemoStock.Common;
using DemoStock.Helper;
using DemoStock.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Media;

namespace DemoStock.ViewModel
{
    public class MainViewModel:NotifyBase
    {
        public ObservableCollection<Record> records { get; set; }
        public MyCommand InputCmd { get; set; }
        public MyCommand CloseCmd { get; set; }
        public MyCommand DeleCmd { get; set; }
        public MyCommand UpdateCommand { get; set; }

        public MyCommand MiniCommand { get; set; }

        public MyCommand SkinCommand { get; set; }
        public Market Market { get; set; }

        private string searchText = "";
        public string SearchText { 
            get {
                return searchText;
            }
            set {
                searchText = value;
                this.Notify();
            } 
        }

        private string skinMode="";
        private MarketSetting marketSetting = null;
        public string StrDate { get => Date; set { Date = value;this.Notify(); } }

        public string SkinMode { get => skinMode; set { skinMode = value; this.Notify(); } }

        private DispatcherTimer timer;
        private Window w = null;
        private string Date;
        public MainViewModel(Window mainWindow)
        {
            records = new ObservableCollection<Record>();
            StrDate = $"{DateTime.Now.Month}月{DateTime.Now.Day}日";
            Market = new Market();
            timer = new DispatcherTimer();
            marketSetting = new MarketSetting();
            w = mainWindow;
            timer.Interval = TimeSpan.FromMilliseconds(1000);
            timer.Tick += Timer_Tick;
            InputCmd = new MyCommand();
            CloseCmd = new MyCommand();
            InputCmd.funcExecute = a => { return true; };
            InputCmd.actExecute = AppendCode;
            CloseCmd.funcExecute = a => { return true; };
            CloseCmd.actExecute = Close;
            DeleCmd = new MyCommand()
            {
                actExecute = Delete,
                funcExecute = a => { return true; }
            };
            UpdateCommand = new MyCommand()
            {
                actExecute = Update,
                funcExecute = a => { return true; }
            };
            MiniCommand = new MyCommand()
            {
                funcExecute = a => { return true; },
                actExecute = Minisize
            };
            SkinCommand = new MyCommand()
            {
                funcExecute = a => { return true; },
                actExecute = ChangeSkin
            };
            w.Closed += W_Closed;
            LoadConfig();
            timer.Start();
        }

        private void W_Closed(object sender, EventArgs e)
        {
            Close(sender);
        }

        private void ChangeSkin(object obj) {
            if (obj is Window wd)
            {
                marketSetting.SkinMode = marketSetting.SkinMode == 1 ? 2 : 1;
                ChangeSkinEx(wd, marketSetting.SkinMode);
            }
        }

        private void Minisize(object obj)
        {
            if (obj is Window window)
            {
                window.WindowState = WindowState.Minimized;
            }
        }
        private void Delete(object obj)
        {
            if (obj == null)
            {
                return;
            }
            string strCode = obj.ToString().ToLower();
            if (string.IsNullOrWhiteSpace(strCode))
            {
                return;
            }
            var res = records.Where(x => x.Code == strCode.ToUpper());
            if (res != null && res.Count() > 0)
            {
                records.Remove(res.First());
            }
        }
        private bool bTime = true;
        private void Update(object obj)
        {
            bTime = false;
            timer.Stop();
            Timer_Tick(null,null);
            timer.Start();
            bTime = true;
        }
        private void Timer_Tick(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;
            if (dt.Hour >= 9 && dt.Hour <= 24|| bTime==false)
            {
                if (records.Count > 0)
                {
                    //string strCodeList = string.Join(',', records.Select(x => x.Code));
                    //string strUrl = string.Format("http://hq.sinajs.cn/list={0}", strCodeList);
                    timer.Stop();
                    foreach (var record in records)
                    {
                        Task.Run(new Action(async () =>
                        {
                            string strMsg = "";
                            try
                            {
                                
                                string strCode = record.Code;
                                string strUrl = string.Format("http://hq.sinajs.cn/list={0}", strCode.ToLower());
                                strMsg = await HttpInfoHelper.GetResponseStringAsync(strUrl,
                                       System.Net.Http.HttpMethod.Get, null);
                                double dNext = new Random().NextDouble();
                                await Task.Delay((int)(100 * dNext));
                                if (!string.IsNullOrWhiteSpace(strMsg))
                                {
                                    Application.Current.Dispatcher.Invoke(new Action(() =>
                                    {
                                        strMsg = strMsg.Replace("var hq_str_" + strCode.ToLower() + "=\"", "").Replace("\";", "");
                                        string[] arrValue = strMsg.Split(',');
                                        if (arrValue.Length > 4)
                                        {
                                            record.Code = strCode.ToUpper();
                                            record.Name = arrValue[0];
                                            record.PrePrice = Convert.ToSingle(arrValue[2]);
                                            var fPrice = Convert.ToSingle(arrValue[3]);
                                            if (fPrice > record.CurPrice)
                                            {
                                                record.ChangeColor = "#eb4d4b";
                                                record.Volume = "↑";
                                            }
                                            else if(fPrice < record.CurPrice)
                                            {
                                                record.ChangeColor = "#6ab04c";
                                                record.Volume = "↓";
                                            }
                                            record.CurPrice = fPrice;
                                            if (record.InitPrice != record.CurPrice - record.PrePrice)
                                            {
                                                record.InitPrice = record.CurPrice - record.PrePrice;
                                            }
                                            record.Precent = (record.CurPrice - record.PrePrice) / record.PrePrice;
                                            if (record.Precent > 0)
                                            {
                                                record.Color = "#eb4d4b";
                                            }
                                            else if (record.Precent == 0)
                                            {
                                                record.Color = "#535c68";
                                            }
                                            else
                                            {
                                                record.Color = "#6ab04c";
                                            }
                                            record.Precent = (float)Math.Round(record.Precent * 100, 2);
                                        }
                                    }));

                                }
                            }
                            catch (Exception ex)
                            {
                                return;
                            }

                        }));
                        

                    }
                    timer.Start();
                }
                Task.Run(new Action(async () =>
                {
                    try
                    {
                        string strCode = "s_sh000001";
                        string strUrl = string.Format("http://hq.sinajs.cn/list={0}", strCode.ToLower());
                        string strMsg = await HttpInfoHelper.GetResponseStringAsync(strUrl,
                               System.Net.Http.HttpMethod.Get, null);

                        if (!string.IsNullOrWhiteSpace(strMsg))
                        {
                            Application.Current.Dispatcher.Invoke(new Action(() =>
                            {
                                strMsg = strMsg.Replace("var hq_str_" + strCode.ToLower() + "=\"", "").Replace("\";", "");
                                string[] arrValue = strMsg.Split(',');
                                if (arrValue.Length > 4)
                                {
                                    Market.Name = arrValue[0];
                                    Market.Price = Convert.ToSingle(arrValue[1]);
                                    Market.UpDownValue = Convert.ToSingle(arrValue[2]);
                                    Market.Precent = Convert.ToSingle(arrValue[3]);
                                    if (Market.Precent > 0)
                                    {
                                        Market.Color = "#eb4d4b";
                                    }
                                    else if (Market.Precent == 0)
                                    {
                                        Market.Color = "#535c68";
                                    }
                                    else
                                    {
                                        Market.Color = "#6ab04c";
                                    }
                                }
                            }));
                        }
                    }
                    catch (Exception ex)
                    {

                    }
                }));
            }
            else
            {
                timer.Stop();
            }
            bTime = true;
        }

        private void Close(object obj)
        {
            if (obj is Window window)
            {
                if (timer != null)
                {
                    timer.Stop();
                }
                SerilizeSave();
                window.Close();
            }
        }
        private void AppendCode(object obj)
        {
            bool bAdd = false;
            if (obj == null)
            {
                return;
            }
            string strCode = obj.ToString().ToLower();
            if (string.IsNullOrWhiteSpace(strCode))
            {
                return;
            }
            int iCount = records.Where(x => x.Code == strCode.ToUpper()).Count();
            if (iCount > 0)
            {
                return;
            }
            string strUrl = string.Format("http://hq.sinajs.cn/list={0}", strCode);
            timer.Stop();
            Task.Run(new Action(async () =>
            {
                string strMsg = "";
                try
                {
                    strMsg = await HttpInfoHelper.GetResponseStringAsync(strUrl,
                           System.Net.Http.HttpMethod.Get, null);

                    if (!string.IsNullOrWhiteSpace(strMsg))
                    {
                        Application.Current.Dispatcher.Invoke(new Action(() =>
                        {
                            strMsg = strMsg.Replace("var hq_str_" + strCode + "=\"", "").Replace("\";", "");
                            string[] arrValue = strMsg.Split(',');
                            if (arrValue.Length > 4)
                            {
                                Record record = new Record();
                                record.Code = strCode.ToUpper();
                                record.Name = arrValue[0];
                                record.PrePrice = Convert.ToSingle(arrValue[2]);
                                record.CurPrice = Convert.ToSingle(arrValue[3]);
                                if (record.InitPrice != record.CurPrice - record.PrePrice)
                                {
                                    record.InitPrice = record.CurPrice - record.PrePrice;
                                }
                                record.Precent = (record.CurPrice - record.PrePrice) / record.PrePrice;
                                if (record.Precent > 0)
                                {
                                    record.Color = "#eb4d4b";
                                }
                                else if (record.Precent == 0)
                                {
                                    record.Color = "#535c68";
                                }
                                else
                                {
                                    record.Color = "#6ab04c";
                                }
                                //record.ChangeColor = "#6ab04c";
                                record.Precent = (float)Math.Round(record.Precent * 100, 2);
                                record.Index = records.Count + 1;
                                records.Add(record);
                                bAdd = true;
                                if (bAdd)
                                {
                                    SearchText = "";
                                }
                            }
                        }));
                            
                    }
                }
                catch(Exception ex)
                {
                    return;
                }

            }));
            
            timer.Start();
        }

        private void SerilizeSave()
        {
            string strFilePath = AppDomain.CurrentDomain.BaseDirectory + @"\StockConfig.byte";
            using (FileStream fileStream = new FileStream(strFilePath, System.IO.FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                try
                {
                    string strCodelst = string.Join(',', records.Select(x=>x.Code).ToList());
                    if (marketSetting == null)
                    {
                        marketSetting = new MarketSetting()
                        {
                            Code = strCodelst
                        };
                    }
                    else

                    {
                        marketSetting.Code = strCodelst;
                    }
                    binaryFormatter.Serialize(fileStream, marketSetting);
                }
                catch(Exception ex)
                {

                }
            }

        }
        private void ChangeSkinEx(Window wd, int iSkinMode)
        {
            if (wd == null)
            {
                return;
            }
            SkinMode = iSkinMode == 1 ? "锐德白" : "锐德黑";
            switch (marketSetting.SkinMode)
            {
                case 1:
                    wd.Resources["forColor"] = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#1E1E1E"));
                    wd.Resources["bakColor"] = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF"));
                    break;
                case 2:
                    //wd.Resources["forColor"] = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#2c3e50"));
                    wd.Resources["forColor"] = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF"));
                    wd.Resources["bakColor"] = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#1E1E1E"));
                    break;
                default:
                    break;
            }
        }
        /// <summary>
        /// 加载配置
        /// </summary>
        /// <returns></returns>
        private void LoadConfig()
        {
            string strFilePath = AppDomain.CurrentDomain.BaseDirectory + @"\StockConfig.byte";
            if (File.Exists(strFilePath) == false)
            {
                ChangeSkinEx(w,1);
                return;
            }
            using (FileStream fileStream = new FileStream(strFilePath, System.IO.FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                try
                {
                    object obj = binaryFormatter.Deserialize(fileStream);
                    if (obj != null)
                    {
                        marketSetting = obj as MarketSetting;
                        if (marketSetting == null)
                        {
                            return;
                        }
                        obj = marketSetting.Code;
                        string strCodelst = obj.ToString();
                        if (!string.IsNullOrWhiteSpace(strCodelst))
                        {
                            string[] arrCodes = strCodelst.Split(',');
                            if (arrCodes != null && arrCodes.Length > 0)
                            {
                                Application.Current.Dispatcher.Invoke(new Action(() =>
                                {
                                    records.Clear();
                                    arrCodes.ToList().ForEach(x => {
                                        Record recd = new Record()
                                        {
                                            Code = x,
                                            Index = records.Count+1
                                        };
                                        records.Add(recd);
                                    });
                                }));
                            }
                        }
                        
                        ChangeSkinEx(w, marketSetting.SkinMode);
                    }
                }
                catch
                {

                }
            }
            bTime = false;
            Timer_Tick(null,null);
            bTime = true;
        }
    } 
}
